package com.wxapp.system.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.constant.pojo.vo.UserVo;
import com.wxapp.common.core.annotation.DelCatch;
import com.wxapp.common.core.annotation.GetCatch;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.condition.ConditionUtil;
import com.wxapp.common.util.copy.CopyUtil;
import com.wxapp.common.util.menuTree.TreeUtil;
import com.wxapp.system.api.pojo.entity.CityDO;
import com.wxapp.system.api.pojo.vm.city.PCityDetailVm;
import com.wxapp.system.api.pojo.vm.city.PCityPageVm;
import com.wxapp.system.api.pojo.vm.city.PCityRelationTreeVm;
import com.wxapp.system.api.pojo.vm.city.PCityRelationVm;
import com.wxapp.system.api.pojo.vo.city.QCitySaveVo;
import com.wxapp.system.api.pojo.vo.city.QCitySearchVo;
import com.wxapp.system.api.pojo.vo.city.QCityUpdateVo;
import com.wxapp.system.service.mapper.CityMapper;
import com.wxapp.system.service.service.CityService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lgl
 * @Description 省市县管理
 * @Datetime 2022/11/10 13:25
 * @Modified By
 */
@Service
@RequiredArgsConstructor
public class CityServiceImpl extends IBaseService implements CityService {

    private final CityMapper cityMapper;
    @Override
    @DelCatch(key = "cityAll")
    public ResultVm<String> save(UserVo userVo, QCitySaveVo qSaveVo) {
        LambdaQueryWrapper<CityDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CityDO::getStatus, true).and(wrappers -> wrappers.eq(CityDO::getName, qSaveVo.getName()).or().eq(CityDO::getCode, qSaveVo.getCode()));
        var aLong = cityMapper.selectCount(wrapper);
        if (aLong > 0) {
            return error("已经存在该城市");
        }
        var saveData = CopyUtil.copyObjectNew(qSaveVo, CityDO::new, (s, r) -> {
            r.setCreateBy(userVo.getId());
            return null;
        });
        cityMapper.insert(saveData);
        return success("保存成功");
    }

    @Override
    @DelCatch(key = "cityAll")
    public ResultVm<String> update(UserVo userVo, QCityUpdateVo qSaveVo) {
        var cityDO = cityMapper.selectById(qSaveVo.getId());
        if (CheckUtil.isNullObject(cityDO)) {
            return error("没有找到该城市信息");
        }
        CopyUtil.copyObject(qSaveVo, cityDO, (s, r) -> {
            r.setUpdateBy(userVo.getId());
            return null;
        });
        cityMapper.updateById(cityDO);
        return success("更新城市成功");
    }

    @Override
    public ResultVm<PCityDetailVm> detail(String id) {
        var cityDO = cityMapper.selectById(id);
        if (CheckUtil.isNullObject(cityDO)) {
            return error("没有找到该城市信息");
        }
        var saveData = CopyUtil.copyObjectNew(cityDO, PCityDetailVm::new, null);
        return success(saveData);
    }

    @Override
    @DelCatch(key = "cityAll")
    public ResultVm<String> delete(String id) {
        var cityDO = cityMapper.selectById(id);
        if (CheckUtil.isNullObject(cityDO)) {
            return error("没有找到该城市信息");
        }
        cityMapper.deleteById(cityDO);
        return success("删除城市成功");
    }

    @Override
    public ResultVm<Page<PCityPageVm>> getPage(QCitySearchVo qCitySearchVo) {
        Map<SFunction<CityDO, ?>, SqlKeyword> condition = new HashMap<>();
        condition.put(CityDO::getName, SqlKeyword.LIKE);
        var sCondition = ConditionUtil.getSCondition(CityDO::new, qCitySearchVo, null, condition,null);
        var deptPage = cityMapper.selectPage(ConditionUtil.getPage(qCitySearchVo, CityDO.class), sCondition);
        return success(CopyUtil.copyPage(deptPage, PCityPageVm::new, null));
    }

    @Override
    @GetCatch(  key = "#pid", expression = 2626560 )
    public ResultVm<List<PCityRelationVm>> relation(String pid) {
        LambdaQueryWrapper<CityDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CityDO::getStatus, true).eq(CheckUtil.isNotNullObject(pid), CityDO::getPid, pid).isNull(CheckUtil.isNullObject(pid), CityDO::getPid).select(CityDO::getId, CityDO::getName);
        var aLong = cityMapper.selectList(wrapper);
        if (CheckUtil.isNullList(aLong)) {
            return success(new ArrayList<>());
        }
        List<PCityRelationVm> pRelationVms = CopyUtil.copyListNew(aLong, PCityRelationVm::new, null);
        return success(pRelationVms);
    }

    @Override
   @GetCatch(key = "cityAll", expression = 2626560 )
    public ResultVm<List<PCityRelationTreeVm>> relationTree(QCitySearchVo qCitySearchVo) {
        Map<SFunction<CityDO, ?>, SqlKeyword> condition = new HashMap<>();
        condition.put(CityDO::getName, SqlKeyword.LIKE);
        var sCondition = ConditionUtil.getSCondition(CityDO::new, qCitySearchVo, null, condition,null);
        List<CityDO> list = cityMapper.selectList(sCondition);
        List<PCityRelationTreeVm> iBaseTreeVos = TreeUtil.buildCopyTree(list, PCityRelationTreeVm::new,null);
        return success(iBaseTreeVos);
    }
}
